"""视觉处理基类模块
提供基础的视觉处理功能接口
"""

import cv2
import numpy as np
from typing import Dict, Any, Optional
import asyncio
import time
from abc import ABC, abstractmethod


class VisionBase(ABC):
    """视觉处理基类"""

    def __init__(self, config: Dict[str, Any]):
        """
        初始化视觉处理模块

        Args:
            config: 配置字典，包含视觉处理参数
        """
        self.config = config
        self.camera_url = config.get(
            "camera_url", "http://127.0.0.1:8080/?action=stream?dummy=param.mjpg"
        )
        self.width = config.get("width", 640)
        self.height = config.get("height", 480)
        self.debug = config.get("debug", True)
        self.cap = None
        self.orgFrame = None
        self._init_camera()
        self._start_capture_task()

    def _init_camera(self) -> None:
        """初始化摄像头"""
        try:
            self.cap = cv2.VideoCapture(self.camera_url)
            if not self.cap.isOpened():
                print("无法打开摄像头")
                self.cap = None
        except Exception as e:
            print(f"摄像头初始化失败: {e}")
            self.cap = None

    def _start_capture_task(self) -> None:
        """启动摄像头数据采集任务"""
        asyncio.create_task(self._update_camera())

    async def _update_camera(self) -> None:
        """更新摄像头数据"""
        while True:
            try:
                if self.cap and self.cap.isOpened():
                    ret, frame = self.cap.read()
                    if ret:
                        self.orgFrame = frame
                await asyncio.sleep(0.033)  # 约30fps
            except Exception as e:
                print(f"摄像头数据更新失败: {e}")
                await asyncio.sleep(1)

    async def get_frame(self) -> Optional[np.ndarray]:
        """
        获取当前帧

        Returns:
            当前帧图像，如果获取失败则返回None
        """
        if self.cap and self.cap.isOpened():
            ret, frame = self.cap.read()
            if ret:
                return frame
        return None

    @abstractmethod
    async def process_frame(self, frame: np.ndarray) -> Dict[str, Any]:
        """
        处理图像帧

        Args:
            frame: 输入图像帧

        Returns:
            处理结果字典
        """
        pass

    @abstractmethod
    async def get_vision_data(self) -> Dict[str, Any]:
        """
        获取视觉处理数据

        Returns:
            包含处理结果和时间戳的字典
        """
        pass

    async def close(self) -> None:
        """关闭摄像头"""
        if self.cap:
            self.cap.release()

    def add_text_to_image(
        self,
        image: np.ndarray,
        text: str,
        position: tuple,
        color: tuple = (0, 0, 0),
        size: int = 20,
    ) -> np.ndarray:
        """
        在图像上添加文字

        Args:
            image: 输入图像
            text: 要添加的文字
            position: 文字位置(x, y)
            color: 文字颜色
            size: 文字大小

        Returns:
            添加文字后的图像
        """
        from PIL import Image, ImageDraw, ImageFont

        image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(image)
        font = ImageFont.truetype(
            "/usr/share/fonts/chinese/simsun.ttc", size, encoding="utf-8"
        )
        draw.text(position, text, color, font=font)
        return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)

    def draw_crosshair(
        self,
        image: np.ndarray,
        center: tuple,
        size: int = 20,
        color: tuple = (255, 255, 0),
    ) -> np.ndarray:
        """
        在图像上绘制十字准线

        Args:
            image: 输入图像
            center: 中心点坐标(x, y)
            size: 准线大小
            color: 准线颜色

        Returns:
            绘制准线后的图像
        """
        x, y = center
        cv2.line(image, (x - size, y), (x + size, y), color, 1)
        cv2.line(image, (x, y - size), (x, y + size), color, 1)
        return image
